#include "function.hpp"

// JS层number类型转化成C++ Int类型
napi_value demo_function::PassingNumberReturnInt(napi_env env, napi_callback_info info)
{
    napi_value res;
    size_t argc = 1;
    napi_value argv[1] = {nullptr};
    napi_status status;
    
    status = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
    STATUS_CHECK(status != napi_ok);
    
    int sum;
    status = napi_get_value_int32(env, argv[0], &sum);
    STATUS_CHECK(status != napi_ok);

    sum = sum << 1;
    status = napi_create_int32(env, sum, &res);
    STATUS_CHECK(status);
    return res;
}

// JS层string类型转化成C++ char[] 类型
napi_value demo_function::PassingStringReturnString(napi_env env, napi_callback_info info) {
    napi_value res;
    size_t argc = 1;
    napi_value argv[1] = {nullptr};
    napi_status status;

    status = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
    STATUS_CHECK(status);

    char buf[BUFF_SIZE];
    size_t length = 0;
    status = napi_get_value_string_utf8(env, argv[0], buf, BUFF_SIZE, &length);
    STATUS_CHECK(status);
    
    std::string bufstr(buf);
    bufstr += " too";
    status = napi_create_string_utf8(env, bufstr.c_str(), bufstr.size(), &res);
    STATUS_CHECK(status);
    return res;
}

// JS层Null类型转化成C++ nullptr 类型
napi_value demo_function::PassingNullReturnNull(napi_env env, napi_callback_info info) {
    napi_value res;
    size_t argc = 1;
    napi_value argv[1] = {nullptr};
    napi_status status;

    status = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
    STATUS_CHECK(status);
    
    napi_valuetype type;
    status = napi_typeof(env, argv[0], &type);
    STATUS_CHECK(status);
    
    if (type == napi_null) {
        status = napi_get_null(env, &res);
        STATUS_CHECK(status);
    } else {
        status = napi_get_undefined(env, &res);
        STATUS_CHECK(status);
    }
    return res;
}

// JS层object类型转化成C++ 类型
napi_value demo_function::PassingObjectReturnObject(napi_env env, napi_callback_info info) {
    napi_value res = nullptr;
    size_t argc = 1;
    napi_value argv[1] = {nullptr};
    napi_status status;

    status = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
    STATUS_CHECK(status);

    // 打印object中的数据
    napi_value nameArray;
    status = napi_get_property_names(env, argv[0], &nameArray); // 获取obj属性的name list
    STATUS_CHECK(status);

    uint32_t length = 0;
    status = napi_get_array_length(env, nameArray, &length); // 获取list 长度
    STATUS_CHECK(status);
    
    for (int i = 0; i < length; i++) {
        napi_value key;
        status = napi_get_element(env, nameArray, i, &key); // 遍历list，获取每个元素的key
        STATUS_CHECK(status);
        
        char key1[BUFF_SIZE] = {0};
        size_t len = 0;
        status = napi_get_value_string_utf8(env, key, key1, BUFF_SIZE, &len);
        STATUS_CHECK(status);
        LOGINFO("key %{public}s", key1);
        
        napi_value value;
        status = napi_get_property(env, argv[0], key, &value); // 通过key获取value
        STATUS_CHECK(status);

        char value1[BUFF_SIZE] = {0};
        size_t vlen = 0;
        status = napi_get_value_string_utf8(env, value, value1, BUFF_SIZE, &vlen);
        STATUS_CHECK(status);
        LOGINFO("value %{public}s", value1);
    }

    napi_value key3, value3;
    status = napi_create_string_utf8(env, "key3", NAPI_AUTO_LENGTH, &key3); // key必须是字符串类型
    STATUS_CHECK(status);
    
    status = napi_create_string_utf8(env, "value3", NAPI_AUTO_LENGTH, &value3); // value可以是任意其他类型，不一定是字符串
    STATUS_CHECK(status);
    
    status = napi_set_property(env, argv[0], key3, value3);
    STATUS_CHECK(status);
    
    return argv[0];
}

napi_value demo_function::Exports(napi_env env, napi_value &exports)
{
    napi_property_descriptor desc[] = {
        {"PassingNumberReturnInt", nullptr, demo_function::PassingNumberReturnInt, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"PassingStringReturnString", nullptr, demo_function::PassingStringReturnString, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"PassingNullReturnNull", nullptr, demo_function::PassingNullReturnNull, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"PassingObjectReturnObject", nullptr, demo_function::PassingObjectReturnObject, nullptr, nullptr, nullptr, napi_default, nullptr}
    };
    
    napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
    return exports;
}

 